﻿namespace Resonator.Core.Services
{
	using System;
	using System.Collections.Generic;
	using System.Globalization;
	using ICSharpCode.SharpZipLib.Zip;
	using Models;
	using Resonator.Domain.Models;
	using Resonator.Domain.Services;

	public class ZipResourceParser : IResourceParser
	{
		private readonly IResourceParserProvider _resourceParserProvider;

		public ZipResourceParser()
			: this( new ResourceParserProvider() )
		{
		}

		public ZipResourceParser(IResourceParserProvider resourceParserProvider)
		{
			if( resourceParserProvider == null )
			{
				throw new ArgumentNullException( "resourceParserProvider" );
			}

			_resourceParserProvider = resourceParserProvider;
		}

		public virtual IList<Resource> Parse(ResourceStream resourceStream)
		{
			return Parse( resourceStream, CultureInfo.InvariantCulture );
		}

		public virtual IList<Resource> Parse(ResourceStream resourceStream, CultureInfo defaultCulture)
		{
			if( resourceStream == null )
			{
				throw new ArgumentNullException( "resourceStream" );
			}
			if( defaultCulture == null )
			{
				throw new ArgumentNullException( "defaultCulture" );
			}

			List<Resource> resources = new List<Resource>();

			using( ZipInputStream zipStream = new ZipInputStream( new NoCloseStream( resourceStream.Stream ) ) )
			{
				ZipEntry entry;
				while( null != (entry = zipStream.GetNextEntry()) )
				{
					if( entry.IsFile )
					{
						ResourceStream entryResourceStream = new ResourceStream( entry.Name, zipStream );

						IResourceParser entryParser = _resourceParserProvider.Get( entryResourceStream );
						if( entryParser == null )
						{
							throw new ResonatorException( "Unable to determine Parser to use based on ResourceStream name '{0}'", resourceStream.Name );
						}

						IList<Resource> entryResources = entryParser.Parse( entryResourceStream );
						resources.AddRange( entryResources );
					}
				}
			}

			return resources;
		}
	}
}